#pragma once

#ifdef RAPIDJSON_EXPORTS
#define RAPIDJSON_API __declspec(dllexport)
#else
#define RAPIDJSON_API __declspec(dllimport)
#endif

#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/pointer.h"


using rjParseFlag = rapidjson::ParseFlag;
using rjDoc = rapidjson::Document;
using rjErrorCode = rapidjson::ParseErrorCode;
using rjValue = rapidjson::Value;
using rjType = rapidjson::Type;
using rjSizeType = rapidjson::SizeType;
using rjAllocator = rapidjson::MemoryPoolAllocator<>;
using rjStringBuffer = rapidjson::StringBuffer;
using rjWriterSB = rapidjson::Writer<rapidjson::StringBuffer>;
using rjPointer = rapidjson::Pointer;
using rjPointerErrorCode = rapidjson::PointerParseErrorCode;
using rjToken = rapidjson::Pointer::Token;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

extern RAPIDJSON_API rjDoc* rapidjson_docment_create();
extern RAPIDJSON_API void rapidjson_docment_destory(rjDoc* pDoc);
extern RAPIDJSON_API BOOL rapidjson_docment_parse(rjDoc* pDoc, const char* json);
extern RAPIDJSON_API BOOL rapidjson_docment_parse_insitu(rjDoc* pDoc, char* json);
extern RAPIDJSON_API rjErrorCode rapidjson_docment_get_parse_error(rjDoc* pDoc);
extern RAPIDJSON_API size_t rapidjson_docment_get_error_offset(rjDoc* pDoc);
extern RAPIDJSON_API rjDoc* rapidjson_docment_swap(rjDoc* pDoc, rjDoc* rhs);
extern RAPIDJSON_API rjAllocator* rapidjson_docment_get_allocator(rjDoc* pDoc);
extern RAPIDJSON_API BOOL rapidjson_value_accept(rjValue* pVal, rjWriterSB* handler);

extern RAPIDJSON_API rjType rapidjson_value_get_type(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_null(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_false(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_true(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_bool(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_object(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_array(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_number(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_int(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_uint(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_int64(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_uint64(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_double(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_string(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_lossless_double(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_float(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_lossless_float(rjValue* pVal);

extern RAPIDJSON_API rjValue* rapidjson_value_create(rjType type);
extern RAPIDJSON_API void rapidjson_value_destory(rjValue* pVal);
extern RAPIDJSON_API rjValue* rapidjson_value_set_null(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_get_bool(rjValue* pVal);
extern RAPIDJSON_API rjValue* rapidjson_value_set_bool(rjValue* pVal, BOOL b);
//Object
extern RAPIDJSON_API rjValue* rapidjson_value_set_object(rjValue* pVal);
extern RAPIDJSON_API rjSizeType rapidjson_value_get_member_count(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_object_empty(rjValue* pVal);
extern RAPIDJSON_API int rapidjson_value_get_members(rjValue* pVal, const char** names, rjValue** values);
extern RAPIDJSON_API BOOL rapidjson_value_has_member(rjValue* pVal, const char* name);
extern RAPIDJSON_API rjValue* rapidjson_value_find_member(rjValue* pVal, const char* name);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member(rjValue* pVal, const char* name, rjValue* val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member_null(rjValue* pVal, const char* name, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member_bool(rjValue* pVal, const char* name, BOOL val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member_int(rjValue* pVal, const char* name, int val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member_int64(rjValue* pVal, const char* name, __int64 val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member_float(rjValue* pVal, const char* name, float val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member_double(rjValue* pVal, const char* name, double val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member_string(rjValue* pVal, const char* name, const char* val, rjSizeType length, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member_array(rjValue* pVal, const char* name, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_add_member_object(rjValue* pVal, const char* name, rjAllocator* allocator);

extern RAPIDJSON_API void rapidjson_value_remove_all_members(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_remove_member(rjValue* pVal, const char* name);
extern RAPIDJSON_API BOOL rapidjson_value_erase_member(rjValue* pVal, const char* name);
//Array
extern RAPIDJSON_API rjValue* rapidjson_value_set_array(rjValue* pVal);
extern RAPIDJSON_API rjSizeType rapidjson_value_get_size(rjValue* pVal);
extern RAPIDJSON_API rjSizeType rapidjson_value_get_capacity(rjValue* pVal);
extern RAPIDJSON_API BOOL rapidjson_value_is_empty(rjValue* pVal);
extern RAPIDJSON_API void rapidjson_value_clear(rjValue* pVal);
extern RAPIDJSON_API rjValue* rapidjson_value_get_at(rjValue* pVal, int index);
extern RAPIDJSON_API int rapidjson_value_get_values(rjValue* pVal, rjValue** values);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback(rjValue* pVal, rjValue* val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback_null(rjValue* pVal, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback_bool(rjValue* pVal, BOOL val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback_int(rjValue* pVal, int val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback_int64(rjValue* pVal, __int64 val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback_float(rjValue* pVal, float val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback_double(rjValue* pVal, double val, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback_string(rjValue* pVal, const char* val, rjSizeType length, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback_array(rjValue* pVal, rjAllocator* allocator);
extern RAPIDJSON_API rjValue* rapidjson_value_pushback_object(rjValue* pVal, rjAllocator* allocator);

extern RAPIDJSON_API rjValue* rapidjson_value_popback(rjValue* pVal);
extern RAPIDJSON_API rjValue* rapidjson_value_erase(rjValue* pVal, int index, int count);
//Number
extern RAPIDJSON_API int rapidjson_value_get_int(rjValue* pVal);
extern RAPIDJSON_API int64_t rapidjson_value_get_int64(rjValue* pVal);
extern RAPIDJSON_API double rapidjson_value_get_double(rjValue* pVal);
extern RAPIDJSON_API float rapidjson_value_get_float(rjValue* pVal);
extern RAPIDJSON_API rjValue* rapidjson_value_set_int(rjValue* pVal, int i);
extern RAPIDJSON_API rjValue* rapidjson_value_set_int64(rjValue* pVal, int64_t i64);
extern RAPIDJSON_API rjValue* rapidjson_value_set_double(rjValue* pVal, double d);
extern RAPIDJSON_API rjValue* rapidjson_value_set_float(rjValue* pVal, float f);
//String
extern RAPIDJSON_API const char* rapidjson_value_get_string(rjValue* pVal);
extern RAPIDJSON_API rjSizeType rapidjson_value_get_string_length(rjValue* pVal);
extern RAPIDJSON_API rjValue* rapidjson_value_set_string(rjValue* pVal, const char* str, rjSizeType length, rjAllocator* allocator);

extern RAPIDJSON_API rjValue* rapidjson_value_swap(rjValue* pVal, rjValue* r);
extern RAPIDJSON_API rjValue* rapidjson_value_copy(rjValue* pVal, rjValue* r, rjAllocator* allocator);

//StringBuffer
extern RAPIDJSON_API rjStringBuffer* rapidjson_string_buffer_create(size_t capacity);
extern RAPIDJSON_API void rapidjson_string_buffer_destory(rjStringBuffer* pStrbuf);
extern RAPIDJSON_API void rapidjson_string_buffer_put(rjStringBuffer* pStrbuf, char c);
extern RAPIDJSON_API void rapidjson_string_buffer_putunsafe(rjStringBuffer* pStrbuf, char c);
extern RAPIDJSON_API void rapidjson_string_buffer_flush(rjStringBuffer* pStrbuf);
extern RAPIDJSON_API void rapidjson_string_buffer_clear(rjStringBuffer* pStrbuf);
extern RAPIDJSON_API void rapidjson_string_buffer_shrink_to_fit(rjStringBuffer* pStrbuf);
extern RAPIDJSON_API void rapidjson_string_buffer_reserve(rjStringBuffer* pStrbuf, size_t count);
extern RAPIDJSON_API char* rapidjson_string_buffer_push(rjStringBuffer* pStrbuf, size_t count);
extern RAPIDJSON_API char* rapidjson_string_buffer_pushunsafe(rjStringBuffer* pStrbuf, size_t count);
extern RAPIDJSON_API void rapidjson_string_buffer_pop(rjStringBuffer* pStrbuf, size_t count);
extern RAPIDJSON_API const char* rapidjson_string_buffer_get_string(rjStringBuffer* pStrbuf);
extern RAPIDJSON_API size_t rapidjson_string_buffer_get_size(rjStringBuffer* pStrbuf);


//Writer
extern RAPIDJSON_API rjWriterSB* rapidjson_writer_create(rjStringBuffer* pStrbuf, size_t levelDepth);
extern RAPIDJSON_API void rapidjson_writer_destory(rjWriterSB* pWriter);
extern RAPIDJSON_API void rapidjson_writer_reset(rjWriterSB* pWriter, rjStringBuffer* pStrbuf);
extern RAPIDJSON_API BOOL rapidjson_writer_is_complete(rjWriterSB* pWriter);
extern RAPIDJSON_API int rapidjson_writer_get_max_decimal_places(rjWriterSB* pWriter);
extern RAPIDJSON_API void rapidjson_writer_set_max_decimal_places(rjWriterSB* pWriter, int maxDecimalPlaces);
extern RAPIDJSON_API BOOL rapidjson_writer_rawvalue(rjWriterSB* pWriter, const char *json, size_t length, rjType type);
extern RAPIDJSON_API BOOL rapidjson_writer_null(rjWriterSB* pWriter);
extern RAPIDJSON_API BOOL rapidjson_writer_bool(rjWriterSB* pWriter, BOOL b);
extern RAPIDJSON_API BOOL rapidjson_writer_int(rjWriterSB* pWriter, int i);
extern RAPIDJSON_API BOOL rapidjson_writer_uint(rjWriterSB* pWriter, unsigned u);
extern RAPIDJSON_API BOOL rapidjson_writer_int64(rjWriterSB* pWriter, __int64 i64);
extern RAPIDJSON_API BOOL rapidjson_writer_uint64(rjWriterSB* pWriter, unsigned __int64 u64);
extern RAPIDJSON_API BOOL rapidjson_writer_double(rjWriterSB* pWriter, double d);
extern RAPIDJSON_API BOOL rapidjson_writer_rawnumber(rjWriterSB* pWriter, const char *str, rjSizeType length, BOOL copy);
extern RAPIDJSON_API BOOL rapidjson_writer_string(rjWriterSB* pWriter, const char *str, rjSizeType length, BOOL copy);
extern RAPIDJSON_API BOOL rapidjson_writer_startobject(rjWriterSB* pWriter);
extern RAPIDJSON_API BOOL rapidjson_writer_key(rjWriterSB* pWriter, const char *str, rjSizeType length, BOOL copy);
extern RAPIDJSON_API BOOL rapidjson_writer_endobject(rjWriterSB* pWriter, rjSizeType memberCount);
extern RAPIDJSON_API BOOL rapidjson_writer_startarray(rjWriterSB* pWriter);
extern RAPIDJSON_API BOOL rapidjson_writer_endarray(rjWriterSB* pWriter, rjSizeType memberCount);

//Pointer
extern RAPIDJSON_API rjPointer* rapidjson_pointer_create(const char* source);
extern RAPIDJSON_API void rapidjson_pointer_destory(rjPointer* pPointer);
extern RAPIDJSON_API BOOL rapidjson_pointer_erase(rjPointer* pPointer, rjValue* root);
extern RAPIDJSON_API rjPointer* rapidjson_pointer_append(rjPointer* pPointer, const char* name);
extern RAPIDJSON_API BOOL rapidjson_pointer_isvalid(rjPointer* pPointer);
extern RAPIDJSON_API size_t rapidjson_pointer_get_parse_error_offset(rjPointer* pPointer);
extern RAPIDJSON_API rjPointerErrorCode rapidjson_pointer_get_parse_error_code(rjPointer* pPointer);
extern RAPIDJSON_API const rjToken* rapidjson_pointer_get_tokens(rjPointer* pPointer);
extern RAPIDJSON_API size_t rapidjson_pointer_get_token_count(rjPointer* pPointer);
extern RAPIDJSON_API BOOL rapidjson_pointer_stringify(rjPointer* pPointer, rjStringBuffer* pStrbuf);
extern RAPIDJSON_API BOOL rapidjson_pointer_stringify_uri_fragment(rjPointer* pPointer, rjStringBuffer* pStrbuf);
extern RAPIDJSON_API rjValue* rapidjson_pointer_create_value2(rjPointer* pPointer, rjValue* root, rjAllocator* allocator, bool *alreadyExist = 0);
extern RAPIDJSON_API rjValue* rapidjson_pointer_create_value(rjPointer* pPointer, rjDoc* pDoc, bool *alreadyExist = 0);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get(rjPointer* pPointer, rjValue* root, size_t *unresolvedTokenIndex = 0);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get_with_default(rjPointer* pPointer, rjDoc* pDoc, rjValue* defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get_with_default_int(rjPointer* pPointer, rjDoc* pDoc, int defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get_with_default_uint(rjPointer* pPointer, rjDoc* pDoc, unsigned defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get_with_default_int64(rjPointer* pPointer, rjDoc* pDoc, __int64 defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get_with_default_uint64(rjPointer* pPointer, rjDoc* pDoc, unsigned __int64 defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get_with_default_float(rjPointer* pPointer, rjDoc* pDoc, float defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get_with_default_double(rjPointer* pPointer, rjDoc* pDoc, double defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get_with_default_string(rjPointer* pPointer, rjDoc* pDoc, const char* defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_get_with_default_bool(rjPointer* pPointer, rjDoc* pDoc, BOOL defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_set(rjPointer* pPointer, rjDoc* pDoc, rjValue* pValue);
extern RAPIDJSON_API rjValue* rapidjson_pointer_set_int(rjPointer* pPointer, rjDoc* pDoc, int val);
extern RAPIDJSON_API rjValue* rapidjson_pointer_set_uint(rjPointer* pPointer, rjDoc* pDoc, unsigned val);
extern RAPIDJSON_API rjValue* rapidjson_pointer_set_int64(rjPointer* pPointer, rjDoc* pDoc, __int64 val);
extern RAPIDJSON_API rjValue* rapidjson_pointer_set_uint64(rjPointer* pPointer, rjDoc* pDoc, unsigned __int64 val);
extern RAPIDJSON_API rjValue* rapidjson_pointer_set_float(rjPointer* pPointer, rjDoc* pDoc, float val);
extern RAPIDJSON_API rjValue* rapidjson_pointer_set_double(rjPointer* pPointer, rjDoc* pDoc, double val);
extern RAPIDJSON_API rjValue* rapidjson_pointer_set_string(rjPointer* pPointer, rjDoc* pDoc, const char* val);
extern RAPIDJSON_API rjValue* rapidjson_pointer_set_bool(rjPointer* pPointer, rjDoc* pDoc, BOOL val);
extern RAPIDJSON_API rjValue* rapidjson_pointer_swap(rjPointer* pPointer, rjDoc* pDoc, rjValue* pValue);


extern RAPIDJSON_API rjValue* rapidjson_create_value_by_pointer(rjDoc* pDoc, rjPointer* pPointer);
extern RAPIDJSON_API rjValue* rapidjson_create_value_by_pointer_string(rjDoc* pDoc, const char* point);
extern RAPIDJSON_API rjValue* rapidjson_get_value_by_pointer(rjValue* root, rjPointer* pPointer, size_t* unresolvedTokenIndex = 0);
extern RAPIDJSON_API rjValue* rapidjson_get_value_by_pointer_string(rjValue* root, const char* point, size_t* unresolvedTokenIndex = 0);
extern RAPIDJSON_API rjValue* rapidjson_get_value_by_pointer_with_default(rjDoc* pDoc, rjPointer* pPointer, rjValue* defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_get_value_by_pointer_with_default_string(rjDoc* pDoc, const char* point, rjValue* defaultValue);
extern RAPIDJSON_API rjValue* rapidjson_set_value_by_pointer(rjDoc* pDoc, rjPointer* pPointer, rjValue* pValue);
extern RAPIDJSON_API rjValue* rapidjson_set_value_by_pointer_string(rjDoc* pDoc, const char* point, rjValue* pValue);
extern RAPIDJSON_API rjValue* rapidjson_swap_value_by_pointer(rjDoc* pDoc, rjPointer* pPointer, rjValue* pValue);
extern RAPIDJSON_API rjValue* rapidjson_swap_value_by_pointer_string(rjDoc* pDoc, const char* point, rjValue* pValue);

#ifdef __cplusplus
}
#endif // __cplusplus
